package com.zhang.learn.thymeleaf.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Slf4j
public class ComplexQueryController {
    private String aa;

    /**
     * 自定义的负载查询
     *
     * @param conditions
     * @return
     * @throws Exception
     */
    @Operation()
    @PostMapping("/complexQuery")
    public List<Object> complexQuery(@RequestBody String conditions) {
        buildWhereSqlStr(conditions);
        return null;
    }

    /**
     * 构建where查询条件
     * @param conditions
     * @return
     */
    private String buildWhereSqlStr(String conditions) {
        StringBuilder resultBuilder = new StringBuilder();
        String begin = "select * from ";
        resultBuilder.append(begin);

        JSONObject queryConditionJsonObj = JSON.parseObject(conditions);

        String fromConditionStr = queryConditionJsonObj.getString("from");
        resultBuilder.append(fromConditionStr);

        JSONArray whereConditionGroup = JSON.parseObject(conditions).getJSONArray("where");
        resultBuilder.append("where");

        for (int i = 0; i < whereConditionGroup.size(); i++) {
            JSONArray group = whereConditionGroup.getJSONArray(i);
            for (int j = 0; j < group.size(); j++) {
                String suffix = "";
                if (j == group.size() - 1) {
                    suffix = "or ";
                } else {
                    suffix = "and ";
                }
                whereConditionProcess(group.getJSONObject(j), resultBuilder, suffix);
            }
        }

        if (resultBuilder.toString().endsWith("and ")) {
            return resultBuilder.substring(0, resultBuilder.length() - 4);
        } else if (resultBuilder.toString().endsWith("or ")) {
            return resultBuilder.substring(0, resultBuilder.length() - 3);
        }
        return "Hello World";
    }

    /**
     * 解析处理每一个where 条件描述信息
     *
     * @param rowWhereCondition
     * @param resultBuilder
     * @param sufix
     */
    private void whereConditionProcess(JSONObject rowWhereCondition,
                                       StringBuilder resultBuilder,
                                       String sufix
    ) {
        String key = rowWhereCondition.getString("key");
        String value = rowWhereCondition.getString("value");

        String operator = rowWhereCondition.getString("operator");
        if (operator.equalsIgnoreCase("eq")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("= '")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("ne")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("<> '")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("lt")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("< '")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("gt")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("> '")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("le")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("<= '")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("ge")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append(">= '")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("contains")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("like '%")
                    .append(value)
                    .append("%' ");
        } else if (operator.equalsIgnoreCase("notcontains")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("not like '%")
                    .append(value)
                    .append("%' ");
        } else if (operator.equalsIgnoreCase("startswith")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("like '")
                    .append(value)
                    .append("%' ");
        } else if (operator.equalsIgnoreCase("endswith")) {
            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("like '%")
                    .append(value)
                    .append("' ");
        } else if (operator.equalsIgnoreCase("between")) {
            String from = rowWhereCondition.getJSONArray("value").getString(0);
            String to = rowWhereCondition.getJSONArray("value").getString(0);
            resultBuilder
                    .append("(")
                    .append(key)
                    .append(" ")
                    .append("between '")
                    .append(from)
                    .append("' ")
                    .append("and '")
                    .append(to)
                    .append("'）");
        } else if (operator.equalsIgnoreCase("notBetween")) {
            String from = rowWhereCondition.getJSONArray("value").getString(0);
            String to = rowWhereCondition.getJSONArray("value").getString(0);
            resultBuilder
                    .append("(")
                    .append(key)
                    .append(" ")
                    .append("not between '")
                    .append(from)
                    .append("' ")
                    .append("and '")
                    .append(to)
                    .append("'）");
        } else if (operator.equalsIgnoreCase("in")) {
            StringBuilder inConditionBuilder = new StringBuilder();
            JSONArray inArray = rowWhereCondition.getJSONArray("value");
            for (int i = 0; i < inArray.size(); i++) {
                inConditionBuilder.append("'").append(inArray.getString(i)).append("'");
                if (i != inArray.size() - 1) {
                    inConditionBuilder.append(",");
                }
            }

            resultBuilder
                    .append(key)
                    .append(" ")
                    .append("in")
                    .append("(")
                    .append(inConditionBuilder)
                    .append(") ");
        }

        resultBuilder.append(sufix);
    }
}
